package com.quartet.modules.service.aspect;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.quartet.api.MapServerException;
import com.quartet.api.ResultErrorEnum;
import com.quartet.modules.customer.entity.TCustomerInfo;
import com.quartet.modules.customer.service.TCustomerInfoService;
import com.quartet.modules.order.entity.TOrder;
import com.quartet.modules.order.service.TOrderService;
import com.quartet.modules.service.dao.TServiceClickCountDao;
import com.quartet.modules.service.entity.TServiceClickCount;
import com.quartet.modules.service.entity.TServiceInfo;
import com.quartet.modules.service.service.TServiceInfoService;
import com.quartet.modules.stock.entity.TTerminalStock;
import com.quartet.utils.DateUtil;
import com.quartet.utils.enums.OrderStatusEnum;
import com.quartet.utils.enums.ServiceStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
@Aspect
@Slf4j
public class AuthKeyValidatedAspect {

//    /*
//     * 将被加强类的注解传入方法参数
//     */
//    private static ApplicationContext applicationContext;

    @Autowired
    private TCustomerInfoService tCustomerInfoService;

    @Autowired
    private TServiceInfoService tServiceInfoService;

    @Autowired
    private TOrderService tOrderService;

    @Autowired
    private TServiceClickCountDao tServiceClickCountDao;

//    @Override
//    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        this.applicationContext = applicationContext;
//    }

    @Pointcut("@annotation(com.quartet.modules.service.aspect.AuthKeyValidated)")
    private void pointcut() {
        log.info("进入访问服务校验拦击");
    }

    @Before("pointcut()")
    public void advice(JoinPoint joinPoint) {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        AuthKeyValidated authKeyValidated = method.getAnnotation(AuthKeyValidated.class);
        String serviceType = authKeyValidated.value();
        boolean validated = authKeyValidated.validated();

        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        String customerCode = request.getHeader("customerCode");
        log.info("param customerCode is: {}", customerCode);
        if (validated) {
            if (StringUtils.isBlank(customerCode)) {
                throw new MapServerException(ResultErrorEnum.NO_ACCESS);
            }
            //校验
            QueryWrapper<TCustomerInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TCustomerInfo::getCustomerCode, customerCode);

            TCustomerInfo tCustomerInfo = tCustomerInfoService.getOne(queryWrapper);
            if (ObjectUtils.isEmpty(tCustomerInfo)) {
                throw new MapServerException(ResultErrorEnum.NO_ACCESS);
            }
            List<TOrder> tOrderList = tOrderService.list(new QueryWrapper<TOrder>().lambda().eq(TOrder::getCustomerCode, customerCode).eq(TOrder::getPaymentStatus, OrderStatusEnum.PAID.getValue()));
            if (ObjectUtils.isEmpty(tOrderList)) {
                throw new MapServerException(ResultErrorEnum.BMKPF004);
            }

            List<String> orderCodeList = tOrderList.stream().map(TOrder::getOrderCode).collect(Collectors.toList());

            List<TServiceInfo> tServiceInfoList = tServiceInfoService.list(new QueryWrapper<TServiceInfo>().lambda().in(TServiceInfo::getOrderCode, orderCodeList).eq(TServiceInfo::getServiceType, serviceType).eq(TServiceInfo::getStatus, ServiceStatusEnum.ENABLE.getValue()));
            if (ObjectUtils.isEmpty(tServiceInfoList)) {
                throw new MapServerException(ResultErrorEnum.BMKPF004);
            }
        } else {
            if (StringUtils.isBlank(customerCode)) {
                return;
            }
            QueryWrapper<TCustomerInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TCustomerInfo::getCustomerCode, customerCode);

            TCustomerInfo tCustomerInfo = tCustomerInfoService.getOne(queryWrapper);
            if (ObjectUtils.isEmpty(tCustomerInfo)) {
                return;
            }
        }
        List<TOrder> tOrderList = tOrderService.list(new QueryWrapper<TOrder>().lambda().eq(TOrder::getCustomerCode, customerCode));
        //此订单没有绑定服务
        if (CollectionUtils.isEmpty(tOrderList)) {
            return;
        }
        List<String> orderCodeList = tOrderList.stream().map(tOrder -> tOrder.getOrderCode()).collect(Collectors.toList());

        //统计访问次数
        log.info("param serviceType is: {}", serviceType);

        TServiceClickCount tServiceClickCount = tServiceClickCountDao.selectOne(new QueryWrapper<TServiceClickCount>().lambda().eq(TServiceClickCount::getServiceType, serviceType).eq(TServiceClickCount::getTime, DateUtil.getCurrentDateTime_Hour()));
        if (ObjectUtils.isEmpty(tServiceClickCount)) {
            TServiceClickCount tServiceClickCount1 = new TServiceClickCount();
            tServiceClickCount1.setCount(1);
            tServiceClickCount1.setServiceType(serviceType);
            tServiceClickCount1.setTime(DateUtil.getCurrentDateTime_Hour());
            tServiceClickCountDao.insert(tServiceClickCount1);
        } else {
            tServiceClickCount.setCount(tServiceClickCount.getCount() + 1);
            tServiceClickCountDao.updateById(tServiceClickCount);
        }
        tServiceInfoService.increaseCount(customerCode,serviceType, orderCodeList);
    }

}
